package ve.com.wayoyo.wuml_case.DibujoDiagramas;

import java.util.ArrayList;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.provider.SyncStateContract.Constants;

public class CompConector {

	//Constantes
	private static final int ORIENTATION_TOP = 1;
    private static final int ORIENTATION_BOTTOM = 2;
    private static final int ORIENTATION_LEFT = 3;
    private static final int ORIENTATION_RIGHT = 4;
    private static final int ORIENTATION_INNER_TOP = 5;
    private static final int ORIENTATION_INNER_BOTTOM = 6;
    private static final int ORIENTATION_INNER_LEFT = 7;
    private static final int ORIENTATION_INNER_RIGHT = 8;
    
	private int _fatherId;
	private int _childId;
    private Point _fatherCenter;
    private Point _childCenter;
    private int _childQuadrant;
    private int _fatherArrowType;
	private int _childArrowType;
	private int _fatherOrientation;
	private int _childOrientation;
	//Puntos para dibujar la linea
	private Point[] _points = new Point[5];

	//Cantidad de puntos
	private int _numberOfPoints;
	 
	//Tipos de Terminaciones de los conectores
	public static class  _arrowType{
		public static final int Asociacion = 0;
		public static final int Herencia = 1;
		public static final int Asociacion_Directa = 2;
		public static final int Agregacion = 3;
		public static final int Composicion = 4;
		public static final int PataDeGallo_PK = 5;
		public static final int PataDeGallo = 6;
		public static final int Union_Simple = 7;
		public static final int Flecha_Llena = 8;
	}
	
	//Terminaciones
	
	public int get_fatherId() {
		return _fatherId;
	}
	
	//Pinters
	private Paint _normalLinePaint;
	

	public CompConector(int fatherID,int childID){
		super();
		_fatherId = fatherID;
		_childId = childID;
		_normalLinePaint = new Paint();
		_normalLinePaint.setColor(Color.BLACK);
		_normalLinePaint.setStrokeWidth(3);
		_fatherArrowType = _arrowType.Herencia;
		
	}
	
	public void set_fatherId(int _fatherId) {
		this._fatherId = _fatherId;
	}
	public int get_childId() {
		return _childId;
	}
	public void set_childId(int _childId) {
		this._childId = _childId;
	}
	public int get_numberOfPoints() {
		return _numberOfPoints;
	}
	public void set_numberOfPoints(int _numberOfPoints) {
		this._numberOfPoints = _numberOfPoints;
	}
	public int get_fatherArrowType() {
		return _fatherArrowType;
	}
	public void set_fatherArrowType(int _fatherArrowType) {
		this._fatherArrowType = _fatherArrowType;
	}
	public int get_childArrowType() {
		return _childArrowType;
	}
	public void set_childArrowType(int _childArrowType) {
		this._childArrowType = _childArrowType;
	}
	
	public void setPointOfLine(int posX,int posY,int index){
		try{
			_points[index].set(posX, posY);
		}catch (Exception e){
			
		}
	}
	
	public void Dibujar(Canvas c,boolean isFcoused,float globalScale,int offSetX,int offSetY) {
		switch (_fatherArrowType) {
		
		case _arrowType.Asociacion:
			c.drawLine((_points[0].x+offSetX)*globalScale, (_points[0].y+offSetY)*globalScale, (_points[1].x+offSetX)*globalScale, (_points[1].y+offSetY)*globalScale, _normalLinePaint);
			break;
		
		case _arrowType.Herencia:	
			dibujarHerencia(c,globalScale,new Point((int)((_points[0].x+offSetX)*globalScale),(int)((_points[0].y+offSetY)*globalScale)),new Point((int)((_points[1].x+offSetX)*globalScale),(int)((_points[1].y+offSetY)*globalScale)),_fatherOrientation);
			break;
			
		default:
			break;
		}
		for (int i = 1; i < _numberOfPoints; i++) {
			if(i != _numberOfPoints-1){
				c.drawLine((_points[i].x+offSetX)*globalScale, (_points[i].y+offSetY)*globalScale, (_points[i+1].x+offSetX)*globalScale, (_points[i+1].y+offSetY)*globalScale, _normalLinePaint);
			}
		}
	}
	
	public void dibujarHerencia(Canvas c,float globalScale,Point begin,Point end,int orientation ) {
		switch (orientation){
		
		case ORIENTATION_TOP:
			c.drawLine(begin.x, begin.y, begin.x+(10*globalScale), begin.y-(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(10*globalScale), begin.y-(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x+(10*globalScale), begin.y-(20*globalScale),begin.x-(10*globalScale), begin.y-(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y-(20*globalScale), end.x, end.y, _normalLinePaint);
			break;
		case ORIENTATION_BOTTOM:
			c.drawLine(begin.x, begin.y, begin.x+(10*globalScale), begin.y+(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(10*globalScale), begin.y+(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x+(10*globalScale), begin.y+(20*globalScale),begin.x-(10*globalScale), begin.y+(20*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y+(20*globalScale), end.x, end.y, _normalLinePaint);
			break;
			
		case ORIENTATION_LEFT:
			c.drawLine(begin.x, begin.y, begin.x-(20*globalScale), begin.y+(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x-(20*globalScale), begin.y-(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x-(20*globalScale),begin.y-(10*globalScale),begin.x-(20*globalScale),begin.y+(10*globalScale),_normalLinePaint);
			c.drawLine(begin.x-(20*globalScale), begin.y, end.x, end.y, _normalLinePaint);
			break;
			
		case ORIENTATION_RIGHT:
			c.drawLine(begin.x, begin.y, begin.x+(20*globalScale), begin.y-(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x, begin.y, begin.x+(20*globalScale), begin.y+(10*globalScale), _normalLinePaint);
			c.drawLine(begin.x+(20*globalScale),begin.y-(10*globalScale),begin.x+(20*globalScale),begin.y+(10*globalScale),_normalLinePaint);
			c.drawLine(begin.x+(20*globalScale), begin.y, end.x, end.y, _normalLinePaint);
			break;
		default:
			c.drawLine(begin.x, begin.y, end.x, end.y, _normalLinePaint);
			break;
		}
		
		
	}
	
	
	public void CalcularConexiones(Componente father, Componente child){
		_fatherCenter = father.get_centerPoint();
		_childCenter = child.get_centerPoint();
		
		int Ax = father.Anchor.x;
		int AxWith = (int) (Ax + father.get_width());
		int Ay = father.Anchor.y;
		int AyHeight = (int) (Ay + father.get_width());
		//Ubicar Cuadrante
		
		if(child.get_centerPoint().y <= Ay){ //Cuadrantes Superiores
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 8;
				_numberOfPoints = 3;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[2] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 2;
				_numberOfPoints = 3;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[2] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 1;
				_numberOfPoints = 4;
				_points[0] = father.get_topAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_TOP;
				_points[3] = child.get_bottomAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_BOTTOM;
				calcularRutaIntermedia();
			}
		}else if( child.get_centerPoint().y >= AyHeight){//Cuadrantes Inferiores
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 6;
				_numberOfPoints = 3;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[2] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 4;
				_numberOfPoints = 3;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[2] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;				
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 5;
				_numberOfPoints = 4;
				_points[0] = father.get_bottomAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_BOTTOM;
				_points[3] = child.get_topAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_TOP;
				calcularRutaIntermedia();
			}
		}else{//Cuadrantes Medios
			if(Ax > child.get_centerPoint().x){// Cuadrante Derecho
				_childQuadrant = 7;
				_numberOfPoints = 4;
				_points[0] = father.get_leftAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_LEFT;
				_points[3] = child.get_rightAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_RIGHT;
				calcularRutaIntermedia();
			}else if (child.get_centerPoint().x > AxWith){ //Cuadrante Izquierdo
				_childQuadrant = 3;
				_numberOfPoints = 4;
				_points[0] = father.get_rightAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_LEFT;
				_points[3] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
				calcularRutaIntermedia();
			}else{
				_childQuadrant = 0;
				_numberOfPoints = 2;
				_points[0] = father.get_leftAnchors().obtenerPosicion();
				_fatherOrientation = ORIENTATION_INNER_LEFT;
				_points[1] = child.get_leftAnchors().obtenerPosicion();
				_childOrientation = ORIENTATION_LEFT;
			}
		}

	}
	
	public void actualizarRuta(Componente father){
		
		int Ax = father.Anchor.x;
		int AxWith = (int) (Ax + father.get_width());
		int Ay = father.Anchor.y;
		int AyHeight = (int) (Ay + father.get_width());
		//Ubicar Cuadrante
		
		if(_childCenter.y <= Ay){ //Cuadrantes Superiores
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 8){
					_childQuadrant = 8;
					_numberOfPoints = 3;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 2){
					_childQuadrant = 2;
					_numberOfPoints = 3;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 1){
					_childQuadrant = 1;
					_numberOfPoints = 4;
					_points[0] = father.get_topAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_TOP;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_bottomAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_BOTTOM;
				}
				calcularRutaIntermedia();
			}
		}else if(_childCenter.y >= AyHeight){//Cuadrantes Inferiores
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 6){
					_childQuadrant = 6;
					_numberOfPoints = 3;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 4){
					_childQuadrant = 4;
					_numberOfPoints = 3;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[2] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 5){
					_childQuadrant = 5;
					_numberOfPoints = 4;
					_points[0] = father.get_bottomAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_BOTTOM;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_topAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_TOP;
				}
				calcularRutaIntermedia();
			}
		}else{//Cuadrantes Medios
			if(Ax > _childCenter.x){// Cuadrante Derecho
				if(_childQuadrant != 7){
					_childQuadrant = 7;
					_numberOfPoints = 4;
					_points[0] = father.get_leftAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_LEFT;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_rightAnchors().obtenerPosicion();
					_childOrientation =ORIENTATION_RIGHT;
				}
				calcularRutaIntermedia();
			}else if (_childCenter.x > AxWith){ //Cuadrante Izquierdo
				if(_childQuadrant != 3){
					_childQuadrant = 3;
					_numberOfPoints = 4;
					_points[0] = father.get_rightAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_RIGHT;
					_points[3] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
				calcularRutaIntermedia();
			}else{
				if(_childQuadrant != 0){
					_childQuadrant = 0;
					_numberOfPoints = 2;
					_points[0] = father.get_leftAnchors().obtenerPosicion();
					_fatherOrientation = ORIENTATION_INNER_LEFT;
					_points[1] = VistaDiagrama.getVista().getDiagrama().getComponenteById(_childId).get_leftAnchors().obtenerPosicion();
					_childOrientation = ORIENTATION_LEFT;
				}
			}
		}
	}
	
	public void calcularRutaIntermedia(){
		switch (_numberOfPoints) {
			case 3:
				_points[1] = new Point(_points[0].x, _points[2].y);
			break;
			case 4:
				if(_childQuadrant == 7 || _childQuadrant == 3){
					int dist = (_points[3].x-_points[0].x)/2;
					_points[1] = new Point((_points[0].x+dist), _points[0].y);
					_points[2] = new Point((_points[0].x+dist), _points[3].y);
				}else{
					int dist = (_points[3].y-_points[0].y)/2;
					_points[1] = new Point(_points[0].x, _points[0].y+dist);
					_points[2] = new Point(_points[3].x, _points[0].y+dist);
				}
			break;
			default:
			break;
		}
	}
	
}
